package com.carol.bigdata.utils

import java.text.SimpleDateFormat
import java.util.TimeZone

// zone为可变参数,个实例相互不影响
// 其他时区上报数据都是传递时间戳,也就是我们永远按照一个时区进行计算,按照小时的差异转化时区,所以不会有时区变化
object TimeUtil {

    val zone: String = "Asia/Shanghai"

    // 天时间format
    def getDayFormat(timezone: String = zone): SimpleDateFormat = {
        val format: SimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd")
        format.setTimeZone(TimeZone.getTimeZone(timezone))
        format
    }

    // 毫秒时间format
    def getMillFormat(timezone: String = zone): SimpleDateFormat = {
        val format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS")
        format.setTimeZone(TimeZone.getTimeZone(timezone))
        format
    }

    // 秒级时间format
    def getSecondFormat(timezone: String = zone): SimpleDateFormat = {
        val format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
        format.setTimeZone(TimeZone.getTimeZone(timezone))
        format
    }

    // 小时级时间format
    def getHourFormat(timezone: String = zone): SimpleDateFormat = {
        val format = new SimpleDateFormat("yyyy-MM-dd HH")
        format.setTimeZone(TimeZone.getTimeZone(timezone))
        format
    }

    // 距离当前时间往前delta天
    def getDeltaDay(delta: Int, timezone: String = zone): String = {
        val statTime = System.currentTimeMillis() + 24 * 3600 * 1000 * delta.toLong
        val day = getDayFormat(timezone = timezone).format(statTime)
        day
    }

    // 距离特定时间往前delta天
    def getTimeDeltaDay(timeStr: String, delta: Int, timezone: String = zone): String = {
        val format = getDayFormat(timezone = timezone)
        val time: Long = format.parse(timeStr.substring(0, 10)).getTime
        val day = time + 24 * 3600 * 1000 * delta.toLong
        format.format(day)
    }

    // 距离当前时间往前delta天小时
    def getDeltaDayHour(delta: Int, hour: Int = 0, timezone: String = zone): String = {
        val statTime = System.currentTimeMillis() + 24 * 3600 * 1000 * delta.toLong + 3600 * 1000 * hour.toLong
        val day = getHourFormat(timezone = timezone).format(statTime)
        day
    }

    // 距离特定时间往前delta天
    def getTimeDeltaDayHour(timeStr: String, delta: Int, hour: Int = 0, timezone: String = zone): String = {
        val format = getHourFormat(timezone = timezone)
        val time: Long = format.parse(timeStr.substring(0, 13)).getTime
        val day = time + 24 * 3600 * 1000 * delta.toLong + 3600 * 1000 * hour.toLong
        format.format(day)
    }

    // 距离特定时间往前delta天,结果可以小时,天呈现
    def getTimeDeltaByMode(timeStr: String, delta: Int, timeMode: String = "day", timezone: String = zone): String = {
        val day = {
            if (timeMode.toLowerCase() == "hour") TimeUtil.getTimeDeltaDayHour(timeStr, -1)
            else TimeUtil.getTimeDeltaDay(timeStr, -1)
        }
        day
    }

    // 获取前day天的list
    def getDeltaDayList(timeStr: String, delta: Int, hour: Int = 0, timezone: String = zone): List[String] = {
        val format = getDayFormat(timezone = timezone)
        val time: Long = format.parse(timeStr.substring(0, 10)).getTime
        var dayList = List[String]()
        for (i <- 0 to delta.abs) {
            val day = if (delta <= 0) time + 24 * 3600 * 1000 * (-i).toLong + 3600 * 1000 * hour.toLong
            else time + 24 * 3600 * 1000 * i.toLong + 3600 * 1000 * hour.toLong
            dayList :+= format.format(day)
        }
        dayList
    }

    // 时间戳转化为字符串 yyyy-MM-dd HH:mm:ss.SSS，默认模式。如果是秒则为yyyy-MM-dd HH:mm:ss
    def timestamp2str(timestamp: String, isMill: Boolean = true, timezone: String = zone): String = {
        val timeS = s"${timestamp}0000000000000"
        val timeM = timeS.substring(0, 13)
        var timeStr: String = getMillFormat(timezone = timezone).format(timeM.toLong)
        if (!isMill)
            timeStr = getSecondFormat(timezone = timezone).format(timeM)
        timeStr
    }

    // 统计日期截取
    def subTimeString(timeStr: String, begIndex: Int = 0, endIndex: Int = 10): String = {
        timeStr.substring(begIndex, endIndex)
    }

    // 时间测试包装器
    def timer[T](code: => T): T = {
        val startTime: Long = System.currentTimeMillis()

        // 运行函数
        val result: T = code
        val deltaTime: Long = System.currentTimeMillis() - startTime
        println(s"运行时长：${deltaTime} ms, 运行结果：${result}")
        result
    }

}


